using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using ERPBackend.Models;
using ERPBackend.Services;

namespace ERPBackend.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class PurchaseOrdersController : ControllerBase
    {
        private readonly IPurchaseOrderService _purchaseOrderService;

        public PurchaseOrdersController(IPurchaseOrderService purchaseOrderService)
        {
            _purchaseOrderService = purchaseOrderService ?? throw new ArgumentNullException(nameof(purchaseOrderService));
        }

        // GET: api/PurchaseOrders
        [HttpGet]
        public async Task<ActionResult<IEnumerable<PurchaseOrder>>> GetPurchaseOrders()
        {
            var purchaseOrders = await _purchaseOrderService.GetAllPurchaseOrdersAsync();
            return Ok(purchaseOrders);
        }

        // GET: api/PurchaseOrders/5
        [HttpGet("{id}")]
        public async Task<ActionResult<PurchaseOrder>> GetPurchaseOrder(int id)
        {
            var purchaseOrder = await _purchaseOrderService.GetPurchaseOrderByIdAsync(id);

            if (purchaseOrder == null)
            {
                return NotFound();
            }

            return Ok(purchaseOrder);
        }

        // GET: api/PurchaseOrders/supplier/5
        [HttpGet("supplier/{supplierId}")]
        public async Task<ActionResult<IEnumerable<PurchaseOrder>>> GetPurchaseOrdersBySupplier(int supplierId)
        {
            var purchaseOrders = await _purchaseOrderService.GetPurchaseOrdersBySupplierIdAsync(supplierId);
            return Ok(purchaseOrders);
        }

        // GET: api/PurchaseOrders/search?orderCode={code}&status={status}&startDate={date}&endDate={date}
        [HttpGet("search")]
        public async Task<ActionResult<IEnumerable<PurchaseOrder>>> SearchPurchaseOrders(
            [FromQuery] string orderCode,
            [FromQuery] int? status,
            [FromQuery] DateOnly? startDate,
            [FromQuery] DateOnly? endDate)
        {
            var purchaseOrders = await _purchaseOrderService.SearchPurchaseOrdersAsync(orderCode, status, startDate, endDate);
            return Ok(purchaseOrders);
        }

        // POST: api/PurchaseOrders
        [HttpPost]
        public async Task<ActionResult<PurchaseOrder>> PostPurchaseOrder(PurchaseOrder purchaseOrder)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            try
            {
                var createdPurchaseOrder = await _purchaseOrderService.CreatePurchaseOrderAsync(purchaseOrder);
                return CreatedAtAction("GetPurchaseOrder", new { id = createdPurchaseOrder.Id }, createdPurchaseOrder);
            }
            catch (ArgumentException ex)
            {
                return BadRequest(ex.Message);
            }
        }

        // PUT: api/PurchaseOrders/5
        [HttpPut("{id}")]
        public async Task<IActionResult> PutPurchaseOrder(int id, PurchaseOrder purchaseOrder)
        {
            if (id != purchaseOrder.Id)
            {
                return BadRequest();
            }

            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            try
            {
                var updated = await _purchaseOrderService.UpdatePurchaseOrderAsync(purchaseOrder);
                if (!updated)
                {
                    return NotFound();
                }
                return NoContent();
            }
            catch (ArgumentException ex)
            {
                return BadRequest(ex.Message);
            }
        }

        // DELETE: api/PurchaseOrders/5
        [HttpDelete("{id}")]
        public async Task<IActionResult> DeletePurchaseOrder(int id)
        {
            try
            {
                var deleted = await _purchaseOrderService.DeletePurchaseOrderAsync(id);
                if (!deleted)
                {
                    return NotFound();
                }
                return NoContent();
            }
            catch (ArgumentException ex)
            {
                return BadRequest(ex.Message);
            }
        }

        // PUT: api/PurchaseOrders/5/review
        [HttpPut("{id}/review")]
        public async Task<IActionResult> ReviewPurchaseOrder(int id, [FromBody] ReviewRequest request)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            try
            {
                var reviewed = await _purchaseOrderService.ReviewPurchaseOrderAsync(id, request.ReviewedBy, request.IsApproved, request.Comments);
                if (!reviewed)
                {
                    return NotFound();
                }
                return NoContent();
            }
            catch (ArgumentException ex)
            {
                return BadRequest(ex.Message);
            }
        }

        // PUT: api/PurchaseOrders/5/close
        [HttpPut("{id}/close")]
        public async Task<IActionResult> ClosePurchaseOrder(int id, [FromBody] CloseRequest request)
        {
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }

            try
            {
                var closed = await _purchaseOrderService.ClosePurchaseOrderAsync(id, request.ClosedBy, request.Reason);
                if (!closed)
                {
                    return NotFound();
                }
                return NoContent();
            }
            catch (ArgumentException ex)
            {
                return BadRequest(ex.Message);
            }
        }

        // 审核请求模型
        public class ReviewRequest
        {
            public int ReviewedBy { get; set; }
            public bool IsApproved { get; set; }
            public string? Comments { get; set; }
        }

        // 关闭请求模型
        public class CloseRequest
        {
            public int ClosedBy { get; set; }
            public string Reason { get; set; } = string.Empty;
        }
    }
}